#pragma warning(disable : 4995) //funcation was marked as deprecated

#include <Windows.h>
#include <Strsafe.h>
#include "concurrency.h"

//----------------------------------------------------------------------------
// MakeProcess
// creates a new process in the system according to the specified parameters.
//
// @param commandToExecute
//		the command that the new process should execute. 
//		usually a command line format string.
//		for example: "notepad.exe"
// @param OutProcessID
//		the process id of the new process that was created.
//		this is a return parameter and memory allocation should be preformed
//		before calling this function.
//
// @ return
//		true if the process was created successfully
//		false in case of an error.
//----------------------------------------------------------------------------
bool WinConcurrency::MakeProcess(string commandToExecute, int *OutProcessID)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
	char *toRun = NULL;

	int length = commandToExecute.size()+1;
	try
	{
		toRun = new char[length];
	}
	catch (std::bad_alloc *e)
	{
		e = NULL;
		return false;
	}

	StringCchCopy(toRun, length, commandToExecute.c_str());

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    // Start the child process. 
    if( !CreateProcess
		(
			NULL,		// no module name (use Command line)	
			toRun,			// Command line
			NULL,           // Process handle not inheritable
			NULL,           // Thread handle not inheritable
			false,          // Set handle inheritance to FALSE
			CREATE_NEW_CONSOLE,              // No creation flags
			NULL,           // Use parent's environment block
			NULL,           // Use parent's starting directory 
			&si,            // Pointer to STARTUPINFO structure
			&pi				// Pointer to PROCESS_INFORMATION structure
		)
	  ) 
    {
		delete[] toRun;
		return false;
    }

	*OutProcessID = pi.dwProcessId;
	delete[] toRun;
	return true;
}

//----------------------------------------------------------------------------
// WaitForProcess
// halts the current process until the specifed process finished.
//
// @param processId
//		the id of the process to wait for
//
// @return
//		none
//----------------------------------------------------------------------------
void WinConcurrency::WaitForProcess(int processId)
{
	
	HANDLE processHandle =  OpenProcess(SYNCHRONIZE, false, processId);
	WaitForSingleObject(processHandle, INFINITE);
	int err = GetLastError();
	CloseHandle( processHandle );
}